package post_to_in_pkg.node;
import java.util.ArrayList;
import java.util.Iterator;

import com.sun.org.apache.xpath.internal.Arg;
import post_to_in_pkg.GlobalConfig;
import post_to_in_pkg.parser.OP_Keyword;
import post_to_in_pkg.parser.Type;;

public class OperatorNode extends Node {

	OP_Keyword word;
	private ArrayList<OperandNode> arguments = null;
	public String[] code = {"", ""};


	public OperatorNode(OP_Keyword agrw) {
		word = agrw;
		if (word.getArgmentNumber() > 0) {
			// prevent resource leaking 
			arguments = new ArrayList<OperandNode>();
			arguments.ensureCapacity(word.getArgmentNumber());

		} else if (word.isVariableParameter()) {
			arguments = new ArrayList<OperandNode>();
		}
	}

	public void fillArgument(OperandNode argument) {
		arguments.add(argument);
	}

	//define my temporary toString() function
	public String toString() {
		String s = "";
		if (!isSymbol()) {
			s = s + word.toString();

			String args = "";
			if (arguments != null) {
				if (word.isVariableParameter()) {
					for (int i = arguments.size() - 1; i >= 0; i--) {
						//如何从该点修改使得能够进行合并和分离嵌套的输入呢
						String s1 = arguments.get(i).getName();  //read in reverse direction
						if (arguments.get(i).isConstStr()) {
							s1 = "\"" + s1 + "\"";
						}
						args = args + s1 + ",";
					}
				} else {
					for (OperandNode iter : arguments) {
						String s1 = iter.getName();
						if (iter.isConstStr()) {
							s1 = "\"" + s1 + "\"";
						}
						args = args + s1 + ",";
					}
				}
				args = args.substring(0, args.length() - 1);
			} else {
				args = "";
			}

			s = s + "(" + args + ");\n";
		} else {
			String symbol;
			switch (word.toString()) {
				case "OP_ADD":
					symbol = "+";
					break;
				case "OP_SUB":
					symbol = "-";
					break;
				case "OP_MUL":
					symbol = "*";
					break;
				case "OP_DIV":
					symbol = "/";
					break;
				default:
					symbol = "";
					break;

			}
			s = arguments.get(0).getName()
					+ " " + symbol + " "
					+ arguments.get(1).getName() + ";";
		}
		return s;
	}

	public String[] toStringList() {
		String[] s = new String[1 + arguments.size()];

		s[0] = word.toString();

		for (int i = 1; i < s.length; i++) {
			s[i] = arguments.get(i - 1).toString();
		}

		return s;
	}

	public boolean isTempNode() {
		return word.getReturnType() == Type.TEMPVAR || word.getReturnType() == Type.BOOL;
	}

	public boolean isReturnVoid() {
		return word.getReturnType() == Type.VOID;
	}

	@Override
	public boolean hasChild() {
		// TODO Auto-generated method stub
		for (OperandNode iter : arguments) {
			if (iter instanceof TempNode) {
				return true;
			}
		}
		return false;
	}

	//	@Override
//	public void printChild(StringBuffer content) {
//		// TODO Auto-generated method stub
//		StringBuffer buffer=new StringBuffer();
//
//		//print the children before printing this node
//		if(arguments!=null) {
//			for(int i=arguments.size()-1;i>=0;i--) {
//				OperandNode iter=arguments.get(i);
//				if(iter instanceof TempNode)
//					iter.printChild(buffer);
//			}
//		}
//		//buffer.append(toString());
//		if(this.isReturnVoid()) {
//			buffer.append(toString());
//		}
//		content=content.insert(0, buffer);
//
//
//	}
	public String[] generateCodes() {
		return generateCodes(GlobalConfig.defaultNestLevel);
	}

	public String[] generateCodes(int NestLevel) {
		if (!isSymbol()) {
			int offset = arguments.size() - 1;
			String[][] Arg_code = new String[offset+1][2];
			for (int i = 0; i <= offset; i++) {
				Arg_code[i] = arguments.get(i).generateCodes(NestLevel);
			}
			//concat the front code together
			//put the synthesized code into { fun() }form
			code[1] =word.toString() + "(";

			for (int i = 0; i <= offset; i++) {
				code[0] = code[0] + "\n" + Arg_code[i][0];
				code[1] = code[1] + Arg_code[i][1] + ",";
			}
			if (code[1].endsWith(",")) {
				code[1] = code[1].substring(0, code[1].length() - 1);
				code[1] += ")";
			}
		} else {  //deal with add, sub , div ,mul
			String[][] operand_code = new String[2][2];
			char op=getSymbol(word.toString());
			if (NestLevel > 0) {
				NestLevel--;  //NestLevel==0出现在这里
				operand_code[0] = arguments.get(0).generateCodes(NestLevel);
				operand_code[1] = arguments.get(1).generateCodes(NestLevel);
			} else {
				NestLevel=GlobalConfig.defaultNestLevel;
				operand_code[0] = arguments.get(0).generateCodes(NestLevel);
				operand_code[1] = arguments.get(1).generateCodes(NestLevel);
			}
			code[0] = code[0] + "\n" + operand_code[0][0] + "\n" + operand_code[1][0];
			code[1]=  "("+operand_code[0][1]+" "+op+" "+operand_code[1][1]+")";
		}
		return code;
	}

	private boolean isSymbol() {
		return word.equals(OP_Keyword.OP_ADD) || word.equals(OP_Keyword.OP_SUB)
				|| word.equals(OP_Keyword.OP_MUL) || word.equals(OP_Keyword.OP_DIV);
	}

	private char getSymbol(String operatorWord) {
		//使用哈希表会更好；
		char symbol;
		switch (word.toString()) {
			case "OP_ADD":
				symbol = '+';
				break;
			case "OP_SUB":
				symbol = '-';
				break;
			case "OP_MUL":
				symbol = '*';
				break;
			case "OP_DIV":
				symbol = '/';
				break;
			default:
				symbol = 'e';
				break;
		}
		return symbol;
	}

}